﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace Zinnia.Common.Core.Imp
{
    /// <summary>
    /// 队列容器
    /// </summary>
    /// <typeparam name="TQuenueMessageContext"></typeparam>
    public class ConcurrentQueueContainer<TQuenueMessageContext> : ConcurrentQueue<TQuenueMessageContext> where TQuenueMessageContext : IQueueMessageContext
    {
        private int _queueSize;
        /// <summary>
        /// 队列栈是否已满
        /// </summary>
        /// <returns></returns>
        public bool QueueIsFull()
        {
            return _queueSize == base.Count;
        }

        public ConcurrentQueueContainer(int queueSize)
        {
            _queueSize = queueSize;
        }
        /// <summary>
        /// 添加上下文到队列
        /// </summary>
        /// <param name="message"></param>
        public void AddQueue(TQuenueMessageContext message)
        {
            if (base.Count < _queueSize)
            {
                base.Enqueue(message);
            }
        }
        /// <summary>
        /// 队列中移除上下文
        /// </summary>
        /// <param name="message"></param>
        public void RemoveQueue(TQuenueMessageContext message)
        {
            base.TryDequeue(out message);
        }
        /// <summary>
        /// 获取当前队列上下文
        /// </summary>
        /// <returns></returns>
        public TQuenueMessageContext GetCurrentQueue()
        {
            TQuenueMessageContext message;
            base.TryPeek(out message);
            return message;
        }
    }


    public delegate void TaskTQuenueMessageContextDelegate(object quenueMessageContext);
    /// <summary>
    /// 队列池
    /// </summary>
    public class ConcurrentQueuePool
    {
        /// <summary>
        /// 队列池实例
        /// </summary>
        public static ConcurrentQueuePool Instance => new ConcurrentQueuePool();
        private ConcurrentQueuePool()
        {
        }

        /// <summary>
        /// 队列字典池
        /// </summary>
        readonly IDictionary<string, ConcurrentQueueContainer<IQueueMessageContext>> _queuePool = new ConcurrentDictionary<string, ConcurrentQueueContainer<IQueueMessageContext>>();

        /// <summary>
        /// 获取指定队列
        /// </summary>
        /// <param name="name">队列名称(调用者必须保证名称的唯一性)</param>
        /// <param name="queueSize">队列大小</param>
        /// <returns></returns>
        public ConcurrentQueueContainer<IQueueMessageContext> CreateConcurrentQueue(string name, int queueSize)
        {
            if (string.IsNullOrWhiteSpace(name))
                throw new ArgumentNullException(name);
            if (!_queuePool.ContainsKey(name))
            {
                _queuePool.Add(name, new ConcurrentQueueContainer<IQueueMessageContext>(queueSize));
            }
            return _queuePool[name];
        }


    }
}
